﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using sscore;
using System.Data.SqlClient;
using System.Data;

namespace DM4
{
    public partial class DM4
    {

        public XMLInfo GetWorkTree(string usrSessionId, bool showall = false)
        {                       
            BeginFunction("GetWorkTree");

            OperationResult userIdOpResult = GetUserIdBySession(usrSessionId);
            XMLInfo xi = new XMLInfo(userIdOpResult);

            if (!userIdOpResult)
            {
                WriteLog(userIdOpResult.Message, MessageType.Error);
                xi.OperResult = userIdOpResult;
                return xi;
            }
            
            UserInfo ui = GetUserInfo(userIdOpResult.Result);
            string where = "";

            if ((ui.UsrAccessLevel != AccessLevel.Admin) || ((ui.UsrAccessLevel == AccessLevel.Admin) && (!showall)))
                where += String.Format("and usr_id = '{0}'", userIdOpResult.Result);

            if ((ui.UsrAccessLevel == AccessLevel.Admin) && (showall))
                where = "";

            string sql = "select * from run_script_header, users where rsh_user_id = usr_id " + where;

            WriteDebugLog(sql);

            try
            {
                //prepare source datatable
                DataTable dtWork = new DataTable("work");
                using (DataColumn id = dtWork.Columns.Add("wId", typeof(Int32)))
                {
                    id.AllowDBNull = false;
                }

                dtWork.Columns.Add("wParentId", typeof(Int32));
                dtWork.Columns.Add("wType", typeof(String));
                dtWork.Columns.Add("wEntity", typeof(String));
                dtWork.Columns.Add("wStart", typeof(DateTime));
                dtWork.Columns.Add("wStop", typeof(DateTime));
                dtWork.Columns.Add("wTime", typeof(TimeSpan));
                dtWork.Columns.Add("wStatus", typeof(String));
                dtWork.Columns.Add("wProgress", typeof(Double));
                dtWork.Columns.Add("wTraffic", typeof(Double));
                dtWork.Columns.Add("wUser", typeof(String));
                dtWork.Columns.Add("wErrors", typeof(Int64));
                dtWork.Columns.Add("wRecords", typeof(Int64));

                dtWork.PrimaryKey = new[] { dtWork.Columns["wId"] };

                SqlCommand sel = new SqlCommand(sql, _conn);

                using (SqlDataReader reader = sel.ExecuteReader())
                {
                    try
                    {
                        int widScript = 1;
                       
                        TimeSpan ScriptTotalTime = TimeSpan.Zero;

                        while (reader.Read())
                        {
                            double scriptTraffic = 0;
                            Int64 scriptErrors = 0;
                            Int64 scriptRecords = 0; 

                            DataRow drScript = dtWork.NewRow();

                            drScript["wId"] = widScript;
                            drScript["wParentId"] = 0;
                            drScript["wType"] = "M";
                            drScript["wEntity"] = reader["rsh_sessions_id"];
                            drScript["wStart"] = reader["rsh_start"];
                            drScript["wStop"] = reader["rsh_stop"];
                            drScript["wStatus"] = reader["rsh_status"];
                            drScript["wUser"] = reader["usr_fullname"];
                            
                            sql = String.Format("select * from tasks where tsk_rsh = {0} ", reader["rsh_id"]);

                            WriteDebugLog(sql);
                            SqlCommand sel2 = new SqlCommand(sql, _conn);

                            //tasks
                            int widTask = widScript + 1;
                            int taskCount = 0;
                            int taskComplete = 0;
                            
                            TimeSpan tasktime = new TimeSpan();

                            double taskTraffic = 0;
                            Int64 taskErrors = 0;
                            Int64 taskRecords = 0; 

                            using (SqlDataReader reader2 = sel2.ExecuteReader())
                            {
                                while (reader2.Read())
                                {
                                    DataRow drTask = dtWork.NewRow();

                                    drTask["wId"] = widTask;
                                    drTask["wParentId"] = widScript;
                                    drTask["wType"] = "T";
                                    drTask["wEntity"] = reader2["tsk_session_id"];
                                    drTask["wStart"] = reader2["tsk_start"];
                                    drTask["wStop"] = reader2["tsk_stop"];
                                    drTask["wStatus"] = reader2["tsk_status"];
                                    //drTask["wUser"] = reader2["usr_fullname"];

                                    //sessions
                                    sql = String.Format("select * from sessions where sess_task = '{0}' ", reader2["tsk_session_id"]);

                                    WriteDebugLog(sql);
                                    SqlCommand sel3 = new SqlCommand(sql, _conn);

                                    int widSession = widTask + 1;
                                    int sessionCount = 0;
                                    int sessionComplete = 0;

                                    using (SqlDataReader reader3 = sel3.ExecuteReader())
                                    {
                                        while (reader3.Read())
                                        {
                                            DataRow drSession = dtWork.NewRow();

                                            drSession["wId"] = widSession;
                                            drSession["wParentId"] = widTask;
                                            drSession["wType"] = "S";
                                            drSession["wEntity"] = reader3["sess_id"];
                                            drSession["wStart"] = reader3["sess_start_time"];
                                            drSession["wStop"] = reader3["sess_end_time"];
                                            drSession["wStatus"] = reader3["sess_status"];
                                            //drSession["wUser"] = reader3["usr_fullname"];
                                            drSession["wErrors"] = reader3["sess_errors"];
                                            drSession["wRecords"] = reader3["sess_records"];
                                            
                                            drSession["wTime"] = new TimeSpan((Int64)reader3["sess_total_time"]);
                                            drSession["wTraffic"] = Convert.ToDouble((Int64)reader3["sess_traffic"]) / 1024 / 1024; // Mbytes;
                                            drSession["wProgress"] = ((double)reader3["sess_progress"]) * 100; 

                                            dtWork.Rows.Add(drSession);

                                            sessionCount++;
                                            if (reader3["sess_status"].ToString() == "C")
                                                sessionComplete++;

                                            tasktime.Add(new TimeSpan((Int64)reader3["sess_total_time"]));

                                            taskTraffic = taskTraffic + (double)drSession["wTraffic"];
                                            taskErrors = taskErrors + (Int64)reader3["sess_errors"]; ;
                                            taskRecords = taskRecords + (Int64)reader3["sess_records"]; 

                                            widSession++;
                                        }
                                    }

                                    if (sessionCount == 0) sessionCount = 1;

                                    drTask["wTime"] = tasktime;
                                    drTask["wTraffic"] = taskTraffic;
                                    drTask["wErrors"] = taskErrors;
                                    drTask["wRecords"] = taskRecords;
                                    drTask["wProgress"] = sessionComplete * 100 / sessionCount; 

                                    dtWork.Rows.Add(drTask);

                                    widTask = widSession + 1;
                                    taskCount++;

                                    scriptTraffic = scriptTraffic + taskTraffic;
                                    scriptErrors = scriptErrors + taskErrors;
                                    scriptRecords = scriptRecords + taskRecords; 

                                    if (reader2["tsk_status"].ToString() == "C")
                                        taskComplete++;
                                }
                            }

                            if (taskCount == 0) taskCount = 1;

                            drScript["wTime"] = ScriptTotalTime;
                            drScript["wTraffic"] = scriptTraffic;
                            drScript["wErrors"] = scriptErrors;
                            drScript["wRecords"] = scriptRecords;
                            drScript["wProgress"] = taskComplete * 100 / taskCount;
                            
                            dtWork.Rows.Add(drScript);
                            widScript = widTask + 1;
                        }

                        WriteLog("Get work tree complete");
                        xi.Load(dtWork);
                    }

                    catch (Exception ex)
                    {
                        WriteLog(ex.Message, MessageType.Error);
                    }
                }
            }

            catch (Exception ex)
            {
                WriteLog(ex.Message, MessageType.Error);
            }

            EndFunction("GetWorkTree");
            xi.OperResult = userIdOpResult;

            return xi;
        }
    }
}
